package com.fengwk.support.util;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.WebApplicationContext;

import com.fengwk.support.exception.BaseException;
import com.fengwk.support.util.LoggerUtils.Logger;

/**
 * 工具类:web相关工具
 */
public class WebUtils {

	private static final Logger LOG = LoggerUtils.getLogger(WebUtils.class);
	
	public final static String SEPARATOR = "/";
	public final static String QUERY = "?";
	public final static String AND = "&";
	
	private final static String[] MOBILE_AGENTS = { "Android", "iPhone", "iPod","iPad", "Windows Phone", "MQQBrowser" }; //定义移动端请求的所有可能类型
	private final static String UNKNOWN = "unknown";
	private final static String DEFAULT_ACCIDENT_IP = "0:0:0:0:0:0:0:1";
	private final static String DEFAULT_IP = "127.0.0.1";
//	private final static String MAC_ADDRESS_PREFIX = "MAC Address = ";
	private final static String HTTP_HEAD_USER_AGENT = "User-Agent";
	private final static String HTTP_HEAD_X_FORWARDED_FOR = "x-forwarded-for";
	private final static String HTTP_HEAD_PROXY_CLIENT_IP = "Proxy-Client-IP";
	private final static String HTTP_HEAD_WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";
	private final static String AJAX_REQUEST_HEAD = "x-requested-with";
	private final static String DEFAULT_COOKIE_PATH = "/";
	private final static String HTML_RESPONSE_CONTENT_TYPE_VALUE = "text/html;charset=utf-8";
	private final static String JSON_RESPONSE_CONTENT_TYPE_VALUE = "application/json;charset=utf-8";
	private final static String JSONP_RESPONSE_CONTENT_TYPE_VALUE = "text/javascript";
	private final static String REQUEST_JSONP_FLAG = "jsonp";
	
	private WebUtils() {
		throw new BaseException("can not instance " + getClass());
	}
	
	/**
	 * 获取当前站点的url
	 * 
	 * @param request
	 * @return 返回当前站点的url,解析失败则返回null
	 */
	public static String getSelfUrl(HttpServletRequest request) {
		String localAddress = request.getLocalAddr();
		if(StringUtils.isBlank(localAddress)) {
			localAddress = SystemUtils.getInternetIp();
			if(StringUtils.isBlank(localAddress)) {
				localAddress = request.getHeader("Remote Address");
			}
		}
		return request.getScheme() + "://" + localAddress + ":" + request.getLocalPort() + request.getContextPath();
	}
	
	/**
	 * 获取domain
	 * 
	 * @param request
	 * @return
	 */
	public static String getDomain(HttpServletRequest request) {
		return getOrigin(request).replaceAll("^" + request.getScheme() + "://", "").replaceAll(":\\S+$", "");
	}
	
	/**
	 * 获取origin
	 * 
	 * @param request
	 * @return
	 */
	public static String getOrigin(HttpServletRequest request) {
		StringBuffer url = request.getRequestURL();
		return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
	}
	
	/**
	 * 获取模块部署的webroot路径
	 * 
	 * @param request
	 * @return
	 */
	public static String getWebRootPath(HttpServletRequest request) {
		String path = request.getServletContext().getRealPath(SEPARATOR).replace("\\", SEPARATOR);
		if(StringUtils.isBlank(path)) {
		    LOG.error("获取WebRootPath异常");
			return null;
		}
		if(path.endsWith(SEPARATOR)) {
			char[] charBuff = path.toCharArray();
			path = new String(charBuff, 0, charBuff.length - 1);
		}
		return path;
	}
	
	/**
	* 移动客户端检查
	* 
	* @param ua
	* @return 移动设备返回true[排除苹果桌面系统]
	*/
	public static boolean checkAgentIsMobile(String ua) {
		if(StringUtils.isBlank(ua)) {
			return false;
		}
		boolean flag = false;
		if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;"))) {
			//排除苹果桌面系统
			if (!ua.contains("Windows NT") && !ua.contains("Macintosh")) {
				for (String item : MOBILE_AGENTS) {
					if (ua.contains(item)) {
						flag = true;
						break;
					}
				}
			}
		}
		return flag;
	}
	
	/**
	 * 移动客户端检查
	 * 
	 * @param request
	 * @return 移动设备返回true[排除苹果桌面系统]
	 */
	public static boolean checkAgentIsMobile(HttpServletRequest request) {
		return checkAgentIsMobile(request.getHeader(HTTP_HEAD_USER_AGENT));
	}
	
	/**
	 * 获取远程用户的ip
	 * 
	 * @param request
	 * @return
	 */
	public static String getRemoteIp(HttpServletRequest request) {
	    String ip = request.getHeader(HTTP_HEAD_X_FORWARDED_FOR);
	    if(ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)){
	        ip = request.getHeader(HTTP_HEAD_PROXY_CLIENT_IP);
	    }
	    if(ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)){
	        ip = request.getHeader(HTTP_HEAD_WL_PROXY_CLIENT_IP);
	    }
	    if(ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)){
	        ip = request.getRemoteAddr();
	    }
	    return ip.equals(DEFAULT_ACCIDENT_IP)?DEFAULT_IP:ip;
	}
	
	/**
	 * 获取mac地址(延迟严重,不可用于服务器单线程内获取,将会造成严重阻塞)
	 * 
	 * @param request
	 * @return
	 */
	@Deprecated
	public static String getMacAddress(HttpServletRequest request) {
		return SystemUtils.getMacAddress(getRemoteIp(request));
	}
	
	/**
	 * 清空session
	 * 
	 * @param request
	 */
	public static void cleanSession(HttpServletRequest request) {
		cleanSession(request.getSession());
	}
	
	/**
	 * 清空session
	 * 
	 * @param session
	 */
	public static void cleanSession(HttpSession session) {
		session.invalidate();
	}
	
	/**
	 * 置入 cookie
	 * 
	 * @param response
	 * @param name 名字
	 * @param value 值
	 * @param expiry 生命周期(秒)
	 * @param domain 域名
	 * @param uri 路径
	 */
	public static void setCookie(HttpServletResponse response, String name, String value, int expiry) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(expiry);// 设置cookie生命周期
		cookie.setHttpOnly(true);// 设置http-only属性
//		cookie.setSecure(false);
		cookie.setPath(DEFAULT_COOKIE_PATH);
		response.addCookie(cookie);
		LOG.debug("setCookie==> name:" + name + " value:" + value);
	}
	
	/**
	 * 获取cookie
	 * 
	 * @param request
	 * @param name
	 * @return
	 */
	public static String getCookie(HttpServletRequest request, String name) {
		Cookie[] cookies = request.getCookies();
		if(ArrayUtils.isBlank(cookies)) {
			return null;
		}
		for(Cookie cookie : cookies) {
			if(cookie.getName().equals(name)) {
				return cookie.getValue();
			}
		}
		return null;
	}
	
	/**
	 * 移除 cookie
	 * 
	 * @param request
	 * @param response
	 * @param name
	 */
	public static void removeCookie(HttpServletRequest request, HttpServletResponse response, String name) {
		if(StringUtils.isEmpty(name)) {
			return;
		}
		Cookie[] cookies = request.getCookies();
		if(ArrayUtils.isBlank(cookies)) {
			return;
		}
		for(int i = 0; i < cookies.length; i ++) {
			if(name.equals(cookies[i].getName())) {
				cookies[i].setMaxAge(0);
				cookies[i].setPath(DEFAULT_COOKIE_PATH);
				response.addCookie(cookies[i]);
				LOG.debug("removeCookie==> name:" + name);
				return;
			}
		}
	}
	
	/**
	 * 向session中置入对象
	 * 
	 * @param request
	 * @param name
	 * @param value
	 */
	public static void setSessionAttribute(HttpServletRequest request, String name, Object value) {
		request.getSession().setAttribute(name, value); 
	}
	
	/**
	 * 移除session中的对象
	 * 
	 * @param request
	 * @param name
	 */
	public static void removeSessionAttribute(HttpServletRequest request, String name) {
		request.getSession().removeAttribute(name);
	}
	
	/**
	 * 获取spring上下文对象
	 * 
	 * @param servletContext
	 * @return
	 */
	public static Object getSpringContext(ServletContext servletContext) {
		return servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
	}
	
	/**
	 * 判断是否为ajax请求
	 * 
	 * @param request
	 * @return
	 */
	public static boolean isAjaxRequest(HttpServletRequest request) {
		if("XMLHttpRequest".equals(request.getHeader(AJAX_REQUEST_HEAD))) {
			return true;
		}
		return false;
	}
	
	/**
	 * 返回html响应
	 * 
	 * @param response
	 * @param json
	 */
	public static void returnHtmlResponse(HttpServletResponse response, String html) {
		try {
			response.setContentType(HTML_RESPONSE_CONTENT_TYPE_VALUE);
			PrintWriter writer = response.getWriter();
			writer.write(html);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 返回json响应
	 * 
	 * @param response
	 * @param json
	 */
	public static void returnJsonResponse(HttpServletResponse response, String json) {
		try {
			response.setContentType(JSON_RESPONSE_CONTENT_TYPE_VALUE);
			PrintWriter writer = response.getWriter();
			writer.write(json);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 返回jsonp响应
	 * 
	 * @param response
	 * @param json
	 */
	public static void returnJsonpResponse(HttpServletResponse response, String json, String jsonpCallBack) {
		try {
			response.setContentType(JSONP_RESPONSE_CONTENT_TYPE_VALUE);
			PrintWriter writer = response.getWriter();
			writer.write("window['" + jsonpCallBack + "'](" + json + ");");
		} catch (IOException e) {
		    LOG.error(e);
		}
	}
	
	public static String getJsonpCallBack(HttpServletRequest request) {
		return request.getParameter(REQUEST_JSONP_FLAG);
	}
	
	/**
	 * get重定向
	 * 
	 * @param response
	 * @param url
	 */
	public static void sendRedirectByGet(HttpServletResponse response, String url) {
		try {
			response.sendRedirect(url);
		} catch (IOException e) {
		    LOG.error(e);
		}
	}
	
	/**
	 * post重定向,只支持浏览器
	 * 
	 * @param response
	 * @param url
	 */
	public static void sendRedirectByPost(HttpServletResponse response, String url) {
		response.setContentType("text/html");
		PrintWriter out = null;
		try {
			out = response.getWriter();
		} catch (IOException e) {
		    LOG.error(e);
			return;
		}
		out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
		out.println("<HTML>");
		out.println("<HEAD><TITLE>sender</TITLE></HEAD>");
		out.println("<BODY>");
		out.println("<form name=\"submitForm\" action=\""+url+"\" method=\"post\">");
		String[] _url = url.split("\\?");
		String queryString = "";
		if(_url.length == 2) {
			queryString = _url[1];
		}
		String[] _queryString = queryString.split("&");
		if(_queryString.length > 0) {
			for(int i = 0; i < _queryString.length; i ++) {
				String paramer = _queryString[i];
				String[] _paramer = paramer.split("=");
				if(_paramer.length == 2) {
					out.println("<input type=\"hidden\" name=\"" + _paramer[0] + "\" value=\"" + _paramer[1] + "\"/>");
				}
			}
		}
		out.println("</from>");
		out.println("<script type=\"text/javascript\">window.document.submitForm.submit();</script> ");
		out.println("</BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
	
}
